level: intermediate
Issue #136 contained a program that demonstrated the way to download files from the internet. After it was released, it was found to fail for some people. Further investigation showed that the function to check the validity of a URL required a unicode (also called "wide") character string. Liberty BASIC uses ASCII strings, so the URL string requires conversion before it is sent to the function. For more on ASCII and unicode, see DEFINITIONS This conversion can be accomplished with the API function from kernel32.dll called MultiByteToWideChar. I've adapted some code provided by Stefan Pendl that uses this function to convert strings.
The function is as follows. If the function succeeds, it returns the unicode string. If it fails, it returns an empty string, and the demo program traps that error. Each argument is commented.
function MultiByteToWideChar$(String$)
'converts any string into unicode
CodePage = 0 : dwFlags = 0
cchMultiByte = -1
lpMultiByteStr$ = String$
cchWideChar = len(String$) * 3
lpWideCharStr$ = space$(cchWideChar)
calldll #kernel32, "MultiByteToWideChar", _
CodePage as ulong, _ 'CP_ACP=0, ansi code page
dwFlags as ulong, _ 'use 0, flags for character translation
lpMultiByteStr$ as ptr,_'the ascii string to convert
cchMultiByte as long, _ 'len of string, -1 for null-terminated string
lpWideCharStr$ as ptr, _'buffer for returned ansi string
cchWideChar as long, _ 'size in wide characters of string buffer
result as long 'returns number of wide characters written to buffer
if result = 0 then
MultiByteToWideChar$ = ""
else
MultiByteToWideChar$ = left$(lpWideCharStr$, result * 2)
end if
end function
UNICODE AND ASCII
Definition of UNICODE from [WikiPedia.org]
Unicode is an industry standard whose goal is to provide the means by which text of all forms and languages can be encoded for use by computers.
The establishment of Unicode has involved an ambitious project to replace existing character encoding schemes, many of which are very limited in size and incompatible with multilingual environments. Unicode has become the largest and most complete character encoding scheme, serving as the dominant such method in the internationalization and localization of computer software. The standard has been implemented in many recent technologies, including XML, the Java programming language, and modern operating systems.
Definition of ASCII from [WikiPedia.org]
ASCII (American Standard Code for Information Interchange), generally pronounced ['ęski], is a character encoding based on the English alphabet. ASCII codes represent text in computers, communications equipment, and other devices that work with text. Most modern character encodings have a historical basis in ASCII.
CORRECTED DEMO
'Download html from given
'URL to file on disk.
'
'Minimum availability Internet Explorer 3.0
'Minimum operating systems Windows NT 4.0, Windows 95
'
'check for valid URL for HTML page:
u$ = MultiByteToWideChar$("http://www.libertybasic.com/index.html")
if u$ = "" then
print "Unable to convert URL to unicode string."
end
end if
'if result = 0, URL is valid
result = ValidURL(u$)
if result = 0 then
'download html from libertybasic.com
downloadresult = DownloadToFile("http://www.libertybasic.com/index.html", DefaultDir$ + "\test.htm")
if downloadresult <> 0 then print "Error downloading libertybasic.com HTML file."
open DefaultDir$ + "\test.htm" for input as #f
test$ = input$(#f, LOF(#f))
close #f
print test$ 'print HTML from file into mainwin
print : print
print "The text above was downloaded from http://www.libertybasic.com/"
else
print "Invalid URL:"; u$
end if
'now attempt to download the banner:
result = DownloadToFile("http://www.libertybasic.com/lb3banner.jpg", DefaultDir$ + "\banner.jpg")
if result <> 0 then
print "Error downloading Liberty BASIC banner."
else
run "mspaint.exe " + chr$(34) + DefaultDir$ + "\banner.jpg" + chr$(34)
print : print : print "Done"
end if
wait
Function DownloadToFile(urlfile$, localfile$)
open "URLmon" for dll as #url
calldll #url, "URLDownloadToFileA",_
0 as long,_ 'null
urlfile$ as ptr,_ 'url to download
localfile$ as ptr,_ 'save file name
0 as long,_ 'reserved, must be 0
0 as long,_ 'callback address, can be 0
DownloadToFile as ulong '0=success
close #url
end function
Function ValidURL(urlfile$)
open "URLmon" for dll as #url
calldll #url, "IsValidURL",_
0 as long,_ 'ignored, must be 0
urlfile$ as ptr,_ 'urlfile to check
0 as ulong,_ 'ignored, must be 0
ValidURL as long
close #url
end function
function MultiByteToWideChar$(String$)
'converts any string into unicode
CodePage = 0 : dwFlags = 0
cchMultiByte = -1
lpMultiByteStr$ = String$
cchWideChar = len(String$) * 3
lpWideCharStr$ = space$(cchWideChar)
calldll #kernel32, "MultiByteToWideChar", _
CodePage as ulong, _ 'CP_ACP=0, ansi code page
dwFlags as ulong, _ 'use 0, flags for character translation
lpMultiByteStr$ as ptr,_'the ascii string to convert
cchMultiByte as long, _ 'len of string, -1 for null-terminated string
lpWideCharStr$ as ptr, _'buffer for returned ansi string
cchWideChar as long, _ 'size in wide characters of string buffer
result as long 'returns number of wide characters written to buffer
if result = 0 then
MultiByteToWideChar$ = ""
else
MultiByteToWideChar$ = left$(lpWideCharStr$, result * 2)
end if
end function